package com.yyy.spring6.aop.example;

/**
 * @Project ：learn_spring
 * @File ：CalculatorLogReconstructedImpl.java
 * @IDE ：IntelliJ IDEA
 * @Author ：自由如风间
 * @Date ：2025/4/2 15:52
 * @Description ：CalculatorLogImpl 豆包 重构版
 */

public class CalculatorLogReconstructedImpl implements Calculator {

    // 日志前缀
    private static final String LOG_PREFIX = "[日志] ";

    @Override
    public int add(int i, int j) {
        return execute("add", i, j, (a, b) -> a + b);
    }

    @Override
    public int sub(int i, int j) {
        return execute("sub", i, j, (a, b) -> a - b);
    }

    @Override
    public int mul(int i, int j) {
        return execute("mul", i, j, (a, b) -> a * b);
    }

    @Override
    public int div(int i, int j) {
        return execute("div", i, j, (a, b) -> a / b);
    }

    /**
     * 通用方法执行模板
     * @param methodName 方法名
     * @param i 参数列表
     * @param calculator 计算逻辑函数式接口
     * @return 计算结果
     */
    private int execute(String methodName, int i, int j, CalculatorFunction calculator) {
        logStart(methodName, i, j);
        int result = calculator.calculate(i, j);
        logResult(methodName, result);
        logEnd(methodName, result);
        return result;
    }

    /**
     * 记录方法开始日志
     * @param methodName 方法名
     * @param args 参数列表
     */
    private void logStart(String methodName, int... args) {
        System.out.printf("%s方法 %s 开始，参数：%s%n",
                LOG_PREFIX,
                methodName,
                String.join(", ", formatArgs(args)));
    }

    /**
     * 记录方法结果日志（内部计算过程）
     * @param methodName 方法名
     * @param result 计算结果
     */
    private void logResult(String methodName, int result) {
        System.out.printf("方法内部 %s 计算结果：%d%n", methodName, result);
    }

    /**
     * 记录方法结束日志
     * @param methodName 方法名
     * @param result 最终结果
     */
    private void logEnd(String methodName, int result) {
        System.out.printf("%s方法 %s 结束，返回值：%d%n%n",
                LOG_PREFIX,
                methodName,
                result);
    }

    /**
     * 参数格式化工具
     * @param args 参数数组
     * @return 格式化后的参数字符串列表
     */
    private String[] formatArgs(int... args) {
        String[] formatted = new String[args.length];
        for (int i = 0; i < args.length; i++) {
            formatted[i] = "arg" + (i + 1) + "=" + args[i];
        }
        return formatted;
    }

    /**
     * 计算逻辑函数式接口
     */
    @FunctionalInterface
    private interface CalculatorFunction {
        int calculate(int a, int b);
    }
}
